﻿using huqiang.Core.HGUI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class PsdToHgui
{
    [UnityEditor.MenuItem("Assets/PSD/ExportHgui")]
    public static void ExportFugiProject()
    {
        var objs = Selection.objects;
        if (objs != null)
        {
            for(int i=0;i<objs.Length;i++)
            {
                string path = AssetDatabase.GetAssetPath(objs[i]);
                if(path.Contains(".psb"))
                {
                    var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                    CreateHGUI(go);
                }
            }
        }
        Debug.Log("Fgui工程导出完毕:"+ System.Environment.CurrentDirectory+"/tmp");
    }
    [UnityEditor.MenuItem("Assets/PSD/ExportUGUI")]
    public static void ExportUGUI()
    {
        var objs = Selection.objects;
        Vector2 size = new Vector2(1920, 1080);
        if (objs != null)
        {
            for (int i = 0; i < objs.Length; i++)
            {
                string path = AssetDatabase.GetAssetPath(objs[i]);
                if (path.Contains(".psb"))
                {
                    var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                    CreateUGUI(go, size);
                }
            }
        }
    }
    static void CreateUGUI(GameObject ui, Vector2 size)
    {
        float hx = size.x * 0.5f;
        float hy = size.y * 0.5f;
        float h = size.y * 0.01f;
        float s = size.y / h;

        Vector3 ori = ui.transform.position;
        var root = new GameObject(ui.name);
        var can = root.AddComponent<Canvas>();
        can.renderMode = RenderMode.ScreenSpaceOverlay;
        int count = ui.transform.childCount;
        List<OrderLayer> tmp = new List<OrderLayer>();
        for (int i = 0; i < count; i++)
        {
            var son = ui.transform.GetChild(i);
            var sr = son.GetComponent<SpriteRenderer>();
            var c = new GameObject(son.name, typeof(RectTransform));
            c.transform.SetParent(root.transform);
            Vector3 os = son.position - ori;
            os.x *= s;
            os.x += hx;
            os.y *= s;
            os.z = 0;
            c.transform.position = os;
            if (sr != null)
            {
                OrderLayer layer = new OrderLayer();
                layer.layer = sr.sortingOrder;
                layer.trans = c.transform;
                tmp.Add(layer);
                var img = c.AddComponent<Image>();
                img.sprite = sr.sprite;
                img.SetNativeSize();
            }
        }
        tmp.Sort((a, b) => { return a.layer < b.layer ? -1 : 1; });
        for (int i = 0; i < tmp.Count; i++)
            tmp[i].trans.SetSiblingIndex(i);
    }
    static void CreateFGUI(GameObject ui, Vector2 size)
    {
        string tn = ui.name;
        var images = CreatePackage(tn);
        string folder = "tmp/" + tn;
        if (!Directory.Exists(folder))
            Directory.CreateDirectory(folder);
        float h = size.y * 0.01f;
        float s = size.y / h;

        XmlDocument doc = new XmlDocument();
        var declara = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
        XmlElement root = doc.CreateElement("component");
        doc.AppendChild(declara);
        doc.AppendChild(root);
        root.SetAttribute("size", size.x.ToString() + "," + size.y.ToString());
        XmlElement displayList = doc.CreateElement("displayList");
        root.AppendChild(displayList);

        Vector3 ori = ui.transform.position;
        int count = ui.transform.childCount;
        List<UIInfo> tmp = new List<UIInfo>();
        for (int i = 0; i < count; i++)
        {
            var son = ui.transform.GetChild(i);
            var sr = son.GetComponent<SpriteRenderer>();
            Vector3 os = son.position - ori;
            os.x *= s;
            os.x += size.x;
            os.y *= s;
            os.z = 0;
            if (sr != null)
            {
                UIInfo layer = new UIInfo();
                layer.layer = sr.sortingOrder;
                layer.size = sr.sprite.rect.size;
                os.x -= size.x * 0.5f;
                os.x -= layer.size.x * 0.5f;
                os.y = size.y - os.y;
                os.y -= layer.size.y * 0.5f;
                layer.pos = os;
                layer.name = sr.name;
                if (images != null)
                    for (int j = 0; j < images.Length; j++)
                    {
                        if (images[j].name == layer.name)
                        {
                            layer.src = images[j].id;
                            break;
                        }
                    }
                layer.img = tn + "_" + sr.name;
                tmp.Add(layer);
            }
        }
        tmp.Sort((a, b) => { return a.layer < b.layer ? -1 : 1; });
        int index = 1;
        for (int i = 0; i < tmp.Count; i++)
        {
            AddImage(doc, displayList, tmp[i], ref index);
        }
        doc.Save(folder + "/" + tn + ".xml");
    }
    static ImageInfo[] CreatePackage(string name)
    {
        char[] buf = new char[9];
        for (int i = 0; i < 9; i++)
        {
            buf[i] = (char)UnityEngine.Random.Range(65, 91);
        }
        XmlDocument doc = new XmlDocument();
        var declara = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
        XmlElement root = doc.CreateElement("packageDescription");
        doc.AppendChild(declara);
        doc.AppendChild(root);

        root.SetAttribute("id", new string(buf));
        XmlElement resources = doc.CreateElement("resources");
        root.AppendChild(resources);
        string folder = "tmp/" + name + "/source";
        string[] files = Directory.GetFiles(folder);
        ImageInfo[] images = new ImageInfo[files.Length];
        for (int i = 0; i < files.Length; i++)
        {
            int l = folder.Length + 1;
            string n = files[i].Substring(l, files[i].Length - l);
            string id = (i + 100).ToString();
            XmlElement img = doc.CreateElement("image");
            img.SetAttribute("id", id);
            img.SetAttribute("name", n);
            img.SetAttribute("path", "/source/");
            resources.AppendChild(img);
            int e = n.LastIndexOf('.');
            images[i].name = n.Substring(0, e);
            images[i].id = id;
        }
        doc.Save("tmp/" + name + "/package.xml");
        return images;
    }
    static XmlElement AddImage(XmlDocument doc, XmlElement element, UIInfo info, ref int count)
    {
        count++;
        XmlElement img = doc.CreateElement("image");
        img.SetAttribute("id", "id_" + count.ToString());
        img.SetAttribute("name", info.name);

        img.SetAttribute("src", info.src);
        img.SetAttribute("fileName", "source/" + info.img + ".png");

        img.SetAttribute("xy", ((int)info.pos.x).ToString() + "," + ((int)info.pos.y).ToString());
        img.SetAttribute("size", ((int)info.size.x).ToString() + "," + ((int)info.size.y).ToString());
        element.AppendChild(img);
        return img;
    }
    class OrderLayer
    {
        public int layer;
        public Transform trans;
    }
    class UIInfo
    {
        public int layer;
        public Vector2 pos;
        public Vector2 size;
        public string name;
        public string img;
        public string src;
    }
    struct ImageInfo
    {
        public string id;
        public string name;
    }
    //[UnityEditor.MenuItem("Assets/Xml/导出lua声明")]
    public static void ExportLua()
    {
        var objs = Selection.objects;
        if (objs != null)
        {
            for (int i = 0; i < objs.Length; i++)
            {
                string path = AssetDatabase.GetAssetPath(objs[i]);
                if (path.Contains(".xml"))
                {
                    CreateLua(path,"tmp");
                }
            }
        }
    }
    public static void CreateLua(string path, string outfolder)
    {
        path = path.Replace('\\', '/');
        int s = path.LastIndexOf('/') + 1;
        int e = path.LastIndexOf('.');
        string name = path.Substring(s, e - s);
        StringBuilder sb = new StringBuilder();
        sb.Append(name);
        sb.Append("UICtrl = class(\"");
        sb.Append(name);
        sb.Append("UICtrl\", UIControl)\n\nfunction ");
        sb.Append(name);
        sb.Append("UICtrl:Init()\n");
        XmlDocument xml = new XmlDocument();
        xml.Load(path);
        var root = xml["component"];
        if (root != null)
        {
            var displayList = root["displayList"];
            if (displayList != null)
                for (int i = 0; i < displayList.ChildNodes.Count; i++)
                {
                    var node = displayList.ChildNodes[i];
                    if (node.Name == "component")
                    {
                        var ele = node as XmlElement;
                        string fileName = ele.GetAttribute("fileName");
                        if (fileName.IndexOf("compoments/") == 0)
                        {
                            string en = ele.GetAttribute("name");
                            sb.Append("    self._");
                            sb.Append(en);
                            sb.Append(" = self._ui:GetChild(\"");
                            sb.Append(en);
                            sb.Append("\")\n");
                        }
                    }
                }
        }
        sb.Append("end\n");
        string savepath = outfolder + "/" + name + "UICtrl.lua";
        File.WriteAllText(savepath, sb.ToString());
        Debug.Log("Lua输出目录:" + savepath);
    }

    static void CreateHGUI(GameObject ui)
    {
        var render = SceneAsset.FindObjectOfType<HGUIRender>();
        if(render==null)
        {
            var go = new GameObject("HGUIRender");
            var trans = go.transform;
            trans.localPosition = Vector3.zero;
            trans.localScale = Vector3.one;
            trans.localRotation = Quaternion.identity;
            render = go.AddComponent<huqiang.Core.HGUI.HGUIRender>();
            render.DesignSize = new Vector2(1920,1080);
        }
        Vector2 size = render.DesignSize;
        float hx = size.x * 0.5f;
        float hy = size.y * 0.5f;
        float h = size.y * 0.01f;
        float s = size.y / h;

        Vector3 ori = ui.transform.position;
        var root = new GameObject(ui.name);
        root.transform.SetParent(render.transform);
        var page = root.AddComponent<huqiang.Helper.HGUI.UIElement>();
        int count = ui.transform.childCount;
        List<OrderLayer> tmp = new List<OrderLayer>();
        for (int i = 0; i < count; i++)
        {
            var son = ui.transform.GetChild(i);
            var sr = son.GetComponent<SpriteRenderer>();
            var c = new GameObject(son.name);
            c.transform.SetParent(root.transform);
            Vector3 os = son.position - ori;
            os.x *= s;
            //os.x += hx;
            os.y *= s;
            os.y -= hy;
            os.z = 0;
            if (sr != null)
            {
                OrderLayer layer = new OrderLayer();
                layer.layer = sr.sortingOrder;
                layer.trans = c.transform;
                tmp.Add(layer);
                var img = c.AddComponent<huqiang.Helper.HGUI.HImage>();
                img.Awake();
                img.Content.Sprite= sr.sprite;
                img.Content.SetNativeSize();
                img.Content.localPosition = os;
            }
            else
            {
                var ele = c.AddComponent<huqiang.Helper.HGUI.UIElement>();
                ele.Content.localPosition = os;
            }
        }
        tmp.Sort((a, b) => { return a.layer < b.layer ? -1 : 1; });
        for (int i = 0; i < tmp.Count; i++)
            tmp[i].trans.SetSiblingIndex(i);
    }
}

